package com.xiaoxu.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaoxu.auth.dao.UserMapper;
import com.xiaoxu.auth.dao.UserRoleMapper;
import com.xiaoxu.auth.model.dto.AuthParamsDto;
import com.xiaoxu.auth.model.dto.UserExt;
import com.xiaoxu.auth.model.po.User;
import com.xiaoxu.auth.model.po.UserRole;
import com.xiaoxu.auth.service.AuthService;
import com.xiaoxu.base.exception.bkSchoolException;
import com.xiaoxu.base.utils.IdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Map;

/**
 * @author xiaoxu
 * @version 1.0
 * @description 微信扫码登录
 * @date 2023/2/2 17:32
 */
@Service("wx_authservice")
@Slf4j
public class WxAuthService implements AuthService {

    private final UserMapper userMapper;
    private final RestTemplate restTemplate;
    private final WxAuthService currentProxy;
    private final UserRoleMapper userRoleMapper;
    @Value("${weixin.appid}")
    String appid;
    @Value("${weixin.secret}")
    String secret;

    public WxAuthService(UserMapper userMapper, RestTemplate restTemplate, @Lazy WxAuthService currentProxy, UserRoleMapper userRoleMapper) {
        this.userMapper = userMapper;
        this.restTemplate = restTemplate;
        this.currentProxy = currentProxy;
        this.userRoleMapper = userRoleMapper;
    }


    @Override
    public UserExt execute(AuthParamsDto authParamsDto) {
        String username = authParamsDto.getUsername();
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null){
            throw new bkSchoolException("用户不存在，无法登录");
        }
        UserExt userExt = new UserExt();
        BeanUtils.copyProperties(user,userExt);
        ArrayList<String> permissions = new ArrayList<>();
        permissions.add("p1");
        userExt.setPermissions(permissions);
        return null;
    }


    /**
     * @description 拿授权码申请令牌，获取用户
     * @param code 授权码
     * @return 用户信息
     */
    public User wxAuth(String code){
        //获取access_token
        Map<String, String> accessToken = getAccess_token(code);
        if (accessToken == null){
            return null;
        }
        //获取用户信息
        String access_token = accessToken.get("access_token");
        String openid = accessToken.get("openid");
        Map<String, String> userinfo = getUserinfo(access_token, openid);
        //添加用户到数据库
        User wxUser = currentProxy.addWxUser(userinfo);
        if (wxUser == null){
            throw new bkSchoolException("登陆失败");
        }
        return wxUser;
    }

    /**
     * @description 获取令牌
     * @param code 授权码
     * @return Map
     */
    private Map<String,String> getAccess_token(String code) {

        String wxUrl_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, appid, secret, code);

        log.info("调用微信接口申请access_token, url:{}", wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.POST, null, String.class);

        String result = exchange.getBody();
        log.info("调用微信接口申请access_token: 返回值:{}", result);

        return JSON.parseObject(result, Map.class);
    }

    /**
     * @description 获取用户信息
     * @param access_token 令牌
     * @param openid openId
     * @return Map
     */
    private Map<String,String> getUserinfo(String access_token,String openid) {

        String wxUrl_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, access_token,openid);

        log.info("调用微信接口申请access_token, url:{}", wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.POST, null, String.class);

        String result = exchange.getBody();
        log.info("调用微信接口申请access_token: 返回值:{}", result);

        return JSON.parseObject(result, Map.class);
    }

    @Transactional
    public User addWxUser(Map<String,String> userInfo_map){
        String unionid = userInfo_map.get("unionid");
        //根据unionid查询数据库
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getWxUnionid, unionid));
        if(user!=null){
            return user;
        }
        user = new User();
        long id = IdGenerator.generateId();
        user.setId(String.valueOf(id));
        user.setWxUnionid(unionid);
        //记录从微信得到的昵称
        user.setNickname(userInfo_map.get("nickname"));
        user.setUserpic(userInfo_map.get("headimgurl"));
        user.setName(userInfo_map.get("nickname"));
        user.setUsername(unionid);
        user.setPassword(unionid);
        user.setUtype("101001");//学生类型
        user.setStatus("1");//用户状态
        user.setCreateTime(LocalDateTime.now());
        int insertCount = userMapper.insert(user);
        if (insertCount<=0){
            throw new bkSchoolException("系统异常，登录失败");
        }
        UserRole xcUserRole = new UserRole();
        xcUserRole.setUserId(String.valueOf(id));
        xcUserRole.setRoleId("17");//学生角色
        userRoleMapper.insert(xcUserRole);
        return user;
    }



}
